#ifndef _PGEVENTMANAGER_H_
#define _PGEVENTMANAGER_H_

#define g_PG_pFrameworkEventManager g_PG_pPaleGemFramework->GetFrameworkEventManager()

#include<list>
#include"PaleGem.h"
#include"Singleton.h"
#include"IEventListener.h"
#include"IEventManager.h"

struct SListenerEx : public IListenerEx
{
	IEventListener* registeredObject;
	int registeredEvent;
	int registeredClass;

	SListenerEx():  registeredEvent (E_UNKNOWN), registeredClass(EC_UNKNOWN){registeredObject=NULL;}
};

/**
PaleGem's generic event manager.
If you need your own event manager for different things, you can 
either derive directly from pgEventManager (lazy, possible performance drawbacks) or you can derive from
IEventManager to implement your own distribution algorhythms.
CAUTION:
Events are dynamically allocated and passed as pointers.
THE EVENTMANAGER TAKES CARE OF FREEING MEMORY FOR EVENTS!
This means events are only existant for one frame, if you need data from and event
longer than one frame, you should make a copy of the data.
*/
class PALEGEM_API pgEventManager
{
private:

	/**
	Fires all events in the queue.
	*/
	void FireEvents();

	/**
	Fires a special event that can be used to save shutdown if a critical error has appeared
	*/
	void FireCriticalErrorEvent();

	/** Here all listeners are queued */
	std::list<SListenerEx*> extendedRegister;
	/** Here all events are queued */
	std::list<IEvent*>	eventQueue;	
	/** Used for listeners who only want to receive critical error events */
	std::list<IEventListener*> errorListeners;
public:

	pgEventManager();
	~pgEventManager();

	void ShutDown();

	void Update(float frameTime);

	void RegisterListener(IEventListener* listener, int eventClass = EC_UNKNOWN, int eventName = E_UNKNOWN );

	void UnregisterListener(IEventListener* listener);

	void RegisterEvent(int eventName, int eventClass, IEventData *pData);

	/**
	Registers only for critical error event (E_ONCRITICAL_ERROR).
	Can be used by classes who need to be notified on critical errors, 
	but otherwhise do not need to receive any updates
	@param pListener Pointer to the listener that wants to receive E_ONCIRTICAL_ERROR events.
	*/
	void RegisterCriticalErrorListener(IEventListener *pListener);

	/**
	Unregisters an error-only listener.
	Should be used by every class that registered for E_ONCRITICAL_ERROR only, 
	otherwhise memory access violation may occur.
	@param pListener The listener that needs to be unregistered.
	*/
	void UnregisterCriticalErrorListener(IEventListener *pListener);
};
#endif